home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
Comm
/
term-source.lha
/
Extras
/
Source
/
term-Source.lha
/
termPhone.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-02-07
|
17KB
|
763 lines
/*
** termPhone.c
**
** Phonebook support routines
**
** Copyright © 1990-1995 by Olaf `Olsen' Barthel
** All Rights Reserved
*/
#include "termGlobal.h"
/* RemoveDialEntry(LONG Entry):
*
* Remove a phone book entry from the dial list.
*/
VOID __regargs
RemoveDialEntry(LONG Entry)
{
LONG Count = Phonebook[Entry] -> Count,i;
for(i = 0 ; i < NumPhoneEntries ; i++)
{
if(Phonebook[i] -> Count > Count)
SPrintf(Phonebook[i] -> Node -> LocalName,"%3ld - %s",Phonebook[i] -> Count--,Phonebook[i] -> Header -> Name);
}
Phonebook[Entry] -> Count = -1;
SPrintf(Phonebook[Entry] -> Node -> LocalName," %s",Phonebook[Entry] -> Header -> Name);
}
/* RemoveDialNode(struct PhoneNode *Node):
*
* Remove a node from the dialing list.
*/
VOID __regargs
RemoveDialNode(struct PhoneNode *Node)
{
if(Node)
{
/* If it's got a name it was built in the phone book panel,
* else the ARexx interface has linked it into the list.
*/
if(Node -> VanillaNode . ln_Name && Node -> VanillaNode . ln_Name[0])
{
LONG Count = Node -> Entry -> Count,i;
/* Adjust all entries. */
for(i = 0 ; i < NumPhoneEntries ; i++)
{
if(Phonebook[i] -> Count > Count)
Phonebook[i] -> Count--;
}
/* Can the index count. */
Node -> Entry -> Count = -1;
}
}
}
/* SortToList(struct PhoneNode *PhoneNode):
*
* Add a node to the dial list.
*/
VOID __regargs
SortToList(struct PhoneNode *PhoneNode)
{
/* No dial list prepared? Let's create one! */
if(!DialList)
{
if(DialList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY))
NewList(DialList);
}
/* Do we have a dial list to mangle? */
if(DialList)
{
struct PhoneNode *NewNode;
/* Create a new node to be added to the dial list. */
if(NewNode = (struct PhoneNode *)AllocVecPooled(sizeof(struct PhoneNode),MEMF_ANY | MEMF_CLEAR))
{
struct PhoneNode *Node = (struct PhoneNode *)DialList -> lh_Head;
/* Take care of the name and the corresponding phone book entry. */
NewNode -> VanillaNode . ln_Name = NewNode -> LocalName;
NewNode -> Entry = PhoneNode -> Entry;
strcpy(NewNode -> LocalName,PhoneNode -> LocalName);
/* Install back-link. */
NewNode -> Entry -> Node = NewNode;
/* Sort the node into the list. */
while(Node -> VanillaNode . ln_Succ)
{
if(Node -> Entry -> Count > NewNode -> Entry -> Count)
{
if(Node == (struct PhoneNode *)DialList -> lh_Head)
AddHead(DialList,&NewNode -> VanillaNode);
else
Insert(DialList,&NewNode -> VanillaNode,Node -> VanillaNode . ln_Pred);
return;
}
Node = (struct PhoneNode *)Node -> VanillaNode . ln_Succ;
}
AddTail(DialList,&NewNode -> VanillaNode);
}
}
}
/* FreeDialList(BYTE ClearAll):
*
* Release the contents of the dial list.
*/
VOID __regargs
FreeDialList(BYTE ClearAll)
{
if(DialList)
{
struct PhoneNode *SubNode,*NextNode;
for(SubNode = (struct PhoneNode *)DialList -> lh_Head ; NextNode = (struct PhoneNode *)SubNode -> VanillaNode . ln_Succ ; SubNode = NextNode)
{
if(ClearAll || !SubNode -> VanillaNode . ln_Name || !SubNode -> VanillaNode . ln_Name[0])
FreeVecPooled(SubNode);
}
FreeVecPooled(DialList);
DialList = NULL;
}
}
/* CreatePhoneList():
*
* Turn the array of pointers to phonebook entries into
* a linked standard Amiga List (gadtools needs this).
*/
struct List *
CreatePhoneList()
{
struct List *PhoneList;
if(Phonebook && NumPhoneEntries)
{
struct PhoneNode *PhoneNode;
if(PhoneList = (struct List *)AllocVecPooled(sizeof(struct List) + NumPhoneEntries * sizeof(struct PhoneNode),MEMF_ANY | MEMF_CLEAR))
{
LONG i;
NewList(PhoneList);
PhoneNode = (struct PhoneNode *)(PhoneList + 1);
for(i = 0 ; i < NumPhoneEntries ; i++)
{
if(Phonebook[i] -> Count != -1)
SPrintf(PhoneNode[i] . LocalName,"%3ld - %s",Phonebook[i] -> Count + 1,Phonebook[i] -> Header -> Name);
else
SPrintf(PhoneNode[i] . LocalName," %s",Phonebook[i] -> Header -> Name);
PhoneNode[i] . VanillaNode . ln_Name = PhoneNode[i] . LocalName;
Phonebook[i] -> Node = &PhoneNode[i];
PhoneNode[i] . Entry = Phonebook[i];
AddTail(PhoneList,&PhoneNode[i]);
}
return(PhoneList);
}
}
else
{
if(PhoneList = (struct List *)AllocVecPooled(sizeof(struct List),MEMF_ANY))
{
NewList(PhoneList);
return(PhoneList);
}
}
return(NULL);
}
/* DeletePhoneList(struct List *PhoneList):
*
* Delete the entries listed in the Amiga List
* created by the routine above.
*/
VOID __regargs
DeletePhoneList(struct List *PhoneList)
{
if(PhoneList)
FreeVecPooled(PhoneList);
}
/* Compare(struct PhoneEntry **A,struct PhoneEntry **B):
*
* Comparison subroutine required by the QuickSort
* call below.
*/
STATIC int __stdargs
Compare(struct PhoneEntry **A,struct PhoneEntry **B)
{
/* Has entry A been selected? */
if((*A) -> Count == -1)
{
/* If entry B isn't selected either, compare the
* names lexically, else entry B is supposed
* to be `smaller' than entry A.
*/
if((*B) -> Count == -1)
return(Stricmp((*A) -> Header -> Name,(*B) -> Header -> Name));
else
return(1);
}
else
{
/* If entry B isn't selected, entry A is supposed
* to be `smaller' than entry B, else return
* the difference between both entries.
*/
if((*B) -> Count == -1)
return(-1);
else
return((*A) -> Count - (*B) -> Count);
}
}
/* SortPhoneEntries():
*
* Sorts the current phone list array in ascending order.
*/
VOID
SortPhoneEntries()
{
qsort((APTR)Phonebook,NumPhoneEntries,sizeof(struct PhoneEntry *),Compare);
}
/* FreeTimeDateNode(struct TimeDateNode *Node):
*
* Free the memory allocated for a TimeDateNode and
* the associated data table.
*/
VOID __regargs
FreeTimeDateNode(struct TimeDateNode *Node)
{
FreeVecPooled(Node -> Table);
FreeVecPooled(Node);
}
/* FreeTimeDateList(struct List *List):
*
* Free a list of TimeDateNodes.
*/
VOID __regargs
FreeTimeDateList(struct List *List)
{
if(List)
{
struct Node *Node = List -> lh_Head,*NextNode;
while(NextNode = Node -> ln_Succ)
{
Remove(Node);
FreeTimeDateNode((struct TimeDateNode *)Node);
Node = NextNode;
}
}
}
/* CopyTimeDateList(struct List *From,struct List *To,BYTE SkipFirst):
*
* Copies the TimeDateNode list from one location into
* another.
*/
VOID __regargs
CopyTimeDateList(struct List *From,struct List *To,BYTE SkipFirst)
{
struct TimeDateNode *FromNode,*ToNode;
FromNode = (struct TimeDateNode *)From -> lh_Head;
if(SkipFirst)
FromNode = (struct TimeDateNode *)FromNode -> VanillaNode . ln_Succ;
while(FromNode -> VanillaNode . ln_Succ)
{
if(ToNode = (struct TimeDateNode *)AllocVecPooled(sizeof(struct TimeDateNode),MEMF_ANY))
{
CopyMem(FromNode,ToNode,sizeof(struct TimeDateNode));
ToNode -> VanillaNode . ln_Name = ToNode -> Buffer;
if(ToNode -> Table = (struct TimeDate *)AllocVecPooled(sizeof(struct TimeDate) * FromNode -> Table[0] . Count,MEMF_ANY))
{
CopyMem(FromNode -> Table,ToNode -> Table,sizeof(struct TimeDate) * FromNode -> Table[0] . Count);
AddTail(To,&ToNode -> VanillaNode);
}
else
FreeVecPooled(ToNode);
}
FromNode = (struct TimeDateNode *)FromNode -> VanillaNode . ln_Succ;
}
}
/* AdaptTimeDateNode(struct TimeDateNode *Node):
*
* Adapt the title and comment of a TimeDateNode.
*/
VOID __regargs
AdaptTimeDateNode(struct TimeDateNode *Node)
{
STRPTR Comment = Node -> Header . Comment[0] ? Node -> Header . Comment : LocaleString(MSG_TERMPHONE_NO_COMMENT_TXT);
if(Node -> Header . Month == -1)
{
if(Node -> Header . Day == -1)
strcpy(Node -> Buffer,LocaleString(MSG_TERMPHONE_STANDARD_SETTINGS_TXT));
else
SPrintf(Node -> Buffer,LocaleString(MSG_TERMPHONE_DAYS_TXT),Comment);
}
else
SPrintf(Node -> Buffer,"%2ld %s » %s",Node -> Header . Day,LocaleString(MSG_TERMPHONE_JAN_TXT + Node -> Header . Month),Comment);
}
/* TimeCompare(struct TimeDate *A,struct TimeDate *B):
*
* Comparison routine required by SortTimeTable().
*/
STATIC int __stdargs
TimeCompare(struct TimeDate *A,struct TimeDate *B)
{
return(((LONG)A -> Time) - ((LONG)B -> Time));
}
/* SortTimeTable(struct TimeDateNode *Node):
*
* Sort the time table associated with a
* TimeDateNode in ascending order.
*/
VOID __regargs
SortTimeTable(struct TimeDateNode *Node)
{
qsort((APTR)Node -> Table,Node -> Table[0] . Count,sizeof(struct TimeDate),TimeCompare);
}
/* BuildTimeList(struct TimeDateNode *Node):
*
* Build a read-to-display time table list from a TimeDateNode.
*/
struct List * __regargs
BuildTimeList(struct TimeDateNode *Node)
{
struct List *List;
if(List = (struct List *)AllocVecPooled(sizeof(struct List) + Node -> Table[0] . Count * sizeof(struct TimeNode),MEMF_ANY | MEMF_CLEAR))
{
struct TimeNode *Time = (struct TimeNode *)(List + 1);
UBYTE LocalBuffer[40];
LONG i;
NewList(List);
for(i = 0 ; i < Node -> Table[0] . Count ; i++)
{
Time[i] . VanillaNode . ln_Name = Time[i] . Name;
Time[i] . Time = Node -> Table[i] . Time;
FormatTime(LocalBuffer,Time[i] . Time / 6,(Time[i] . Time % 6) * 10,-1);
LocalBuffer[19] = 0;
strcpy(Time[i] . Name,LocalBuffer);
AddTail(List,&Time[i]);
}
}
return(List);
}
/* ResizeTimeDateNode(struct TimeDateNode *Node,LONG Count,UBYTE Time):
*
* Resize the time table associated with a TimeDateNode.
*/
BYTE __regargs
ResizeTimeDateNode(struct TimeDateNode *Node,LONG Count,UBYTE Time)
{
if(Count != Node -> Table[0] . Count)
{
struct TimeDate *Table;
if(Table = (struct TimeDate *)AllocVecPooled(sizeof(struct TimeDate) * Count,MEMF_ANY | MEMF_CLEAR))
{
LONG i;
CopyMem(Node -> Table,Table,sizeof(struct TimeDate) * Count);
if(Count > Node -> Table[0] . Count)
{
for(i = Node -> Table[0] . Count ; i < Count ; i++)
{
CopyMem(&Node -> Table[0],&Table[i],sizeof(struct TimeDate));
Table[i] . Time = Time;
}
}
for(i = 0 ; i < Count ; i++)
Table[i] . Count = Count;
FreeVecPooled(Node -> Table);
Node -> Table = Table;
return(TRUE);
}
else
return(FALSE);
}
else
return(TRUE);
}
/* DeleteTimeDateNode(struct TimeDateNode *Node,LONG Index):
*
* Delete a single timetable entry from a TimeDateNode.
*/
BYTE __regargs
DeleteTimeDateNode(struct TimeDateNode *Node,LONG Index)
{
struct TimeDate *Table;
LONG Count = Node -> Table[0] . Count - 1;
if(Table = (struct TimeDate *)AllocVecPooled(sizeof(struct TimeDate) * Count,MEMF_ANY | MEMF_CLEAR))
{
LONG i,j;
for(i = j = 0 ; i < Node -> Table[0] . Count ; i++)
{
if(i != Index)
{
CopyMem(&Node -> Table[i],&Table[j],sizeof(struct TimeDate));
Table[j++] . Count = Count;
}
}
FreeVecPooled(Node -> Table);
Node -> Table = Table;
return(TRUE);
}
else
return(FALSE);
}
/* CreateTimeDateNode(BYTE Month,BYTE Day,STRPTR Comment,LONG Count):
*
* Create a new TimeDateNode including time table entries.
*/
struct TimeDateNode * __regargs
CreateTimeDateNode(BYTE Month,BYTE Day,STRPTR Comment,LONG Count)
{
struct TimeDateNode *Node;
if(Node = (struct TimeDateNode *)AllocVecPooled(sizeof(struct TimeDateNode),MEMF_ANY | MEMF_CLEAR))
{
if(Node -> Table = (struct TimeDate *)AllocVecPooled(sizeof(struct TimeDate) * Count,MEMF_ANY | MEMF_CLEAR))
{
Node -> VanillaNode . ln_Name = Node -> Buffer;
Node -> Header . Month = Month;
Node -> Header . Day = Day;
/*
Node -> Table[0] . PayPerUnit[DT_FIRST_UNIT] = 23;
Node -> Table[0] . SecPerUnit[DT_FIRST_UNIT] = 6 * 60;
Node -> Table[0] . PayPerUnit[DT_NEXT_UNIT] = 23;
Node -> Table[0] . SecPerUnit[DT_NEXT_UNIT] = 6 * 60;
*/
Node -> Table[0] . PayPerUnit[DT_FIRST_UNIT] = 0;
Node -> Table[0] . SecPerUnit[DT_FIRST_UNIT] = 0;
Node -> Table[0] . PayPerUnit[DT_NEXT_UNIT] = 0;
Node -> Table[0] . SecPerUnit[DT_NEXT_UNIT] = 0;
Node -> Table[0] . Time = DT_GET_TIME( 8,0);
Node -> Table[0] . Count = Count;
if(Count > 1)
{
/*
Node -> Table[1] . PayPerUnit[DT_FIRST_UNIT] = 23;
Node -> Table[1] . SecPerUnit[DT_FIRST_UNIT] = 12 * 60;
Node -> Table[1] . PayPerUnit[DT_NEXT_UNIT] = 23;
Node -> Table[1] . SecPerUnit[DT_NEXT_UNIT] = 12 * 60;
*/
Node -> Table[1] . PayPerUnit[DT_FIRST_UNIT] = 0;
Node -> Table[1] . SecPerUnit[DT_FIRST_UNIT] = 0;
Node -> Table[1] . PayPerUnit[DT_NEXT_UNIT] = 0;
Node -> Table[1] . SecPerUnit[DT_NEXT_UNIT] = 0;
Node -> Table[1] . Time = DT_GET_TIME(18,0);
Node -> Table[1] . Count = Count;
}
strcpy(Node -> Header . Comment,Comment);
AdaptTimeDateNode(Node);
return(Node);
}
else
FreeVecPooled(Node);
}
return(NULL);
}
/* RemPhoneEntry(LONG Num):
*
* Remove a given entry from the phone book.
*/
VOID __regargs
RemPhoneEntry(LONG Num)
{
struct PhoneEntry *Entry;
LONG i;
Entry = Phonebook[Num];
for(i = Num ; i < NumPhoneEntries ; i++)
Phonebook[i] = Phonebook[i + 1];
Phonebook[NumPhoneEntries--] = NULL;
if(Entry -> Config)
DeleteConfiguration(Entry -> Config);
FreeTimeDateList((struct List *)&Entry -> TimeDateList);
FreeVecPooled(Entry);
}
/* NewPhoneEntry():
*
* Create a new phone book entry with default values and
* add it to the array. Expand the phone book if necessary.
*/
BYTE
NewPhoneEntry()
{
struct PhoneEntry **PrivatePhonebook;
LONG PrivatePhoneSize,i;
/* The phone book is filled `to the brim', so let's expand
* it.
*/
if(NumPhoneEntries + 1 > PhoneSize)
{
/* Allocate another phone book. */
if(PrivatePhonebook = CreatePhonebook(PhoneSize + 1,&PrivatePhoneSize,FALSE))
{
/* Copy the data. */
if(Phonebook && PhoneSize)
{
for(i = 0 ; i < PhoneSize ; i++)
PrivatePhonebook[i] = Phonebook[i];
/* Remove the old phonebook. */
DeletePhonebook(Phonebook,PhoneSize,FALSE);
}
/* Assign the new pointers. */
Phonebook = PrivatePhonebook;
PhoneSize = PrivatePhoneSize;
}
else
return(FALSE);
}
/* Allocate another entry and add it to the phone book. */
if(Phonebook[NumPhoneEntries] = (struct PhoneEntry *)AllocVecPooled(sizeof(struct PhoneEntry) + sizeof(struct PhoneHeader),MEMF_ANY | MEMF_CLEAR))
{
if(Phonebook[NumPhoneEntries] -> Config = CreateConfiguration(FALSE))
{
struct TimeDateNode *TimeDateNode;
Phonebook[NumPhoneEntries] -> Header = (struct PhoneHeader *)(Phonebook[NumPhoneEntries] + 1);
strcpy(Phonebook[NumPhoneEntries] -> Header -> Name,LocaleString(MSG_TERMPHONE_UNUSED_ENTRY_TXT));
Phonebook[NumPhoneEntries] -> Count = -1;
NewList((struct List *)&Phonebook[NumPhoneEntries] -> TimeDateList);
if(TimeDateNode = CreateTimeDateNode(-1,-1,"",2))
AddTail((struct List *)&Phonebook[NumPhoneEntries] -> TimeDateList,&TimeDateNode -> VanillaNode);
NumPhoneEntries++;
return(TRUE);
}
FreeVecPooled(Phonebook[NumPhoneEntries]);
Phonebook[NumPhoneEntries] = NULL;
}
return(FALSE);
}
/* CreatePhonebook(LONG Size,LONG *AllocSize,BYTE CreateEntries):
*
* Create a new phone entry array (so-called phone book).
*/
struct PhoneEntry ** __regargs
CreatePhonebook(LONG Size,LONG *AllocSize,BYTE CreateEntries)
{
struct PhoneEntry **PhoneEntry = NULL;
if(Size)
{
/* Round the number of phone entries to a
* multiple of eight.
*/
*AllocSize = (Size + 7) & ~7;
/* Create the list of pointers. */
if(PhoneEntry = (struct PhoneEntry **)AllocVecPooled(*AllocSize * sizeof(struct PhoneEntry *),MEMF_ANY | MEMF_CLEAR))
{
/* And create some entries if necessary. */
if(CreateEntries)
{
BYTE Success = TRUE;
LONG i;
for(i = 0 ; Success && i < Size ; i++)
{
if(PhoneEntry[i] = (struct PhoneEntry *)AllocVecPooled(sizeof(struct PhoneEntry) + sizeof(struct PhoneHeader),MEMF_ANY | MEMF_CLEAR))
{
if(PhoneEntry[i] -> Config = CreateConfiguration(FALSE))
{
PhoneEntry[i] -> Header = (struct PhoneHeader *)(PhoneEntry[i] + 1);
NewList((struct List *)&PhoneEntry[i] -> TimeDateList);
}
else
Success = FALSE;
}
else
Success = FALSE;
}
if(!Success)
{
for(i = 0 ; i < *AllocSize ; i++)
{
if(PhoneEntry[i])
{
if(PhoneEntry[i] -> Config)
DeleteConfiguration(PhoneEntry[i] -> Config);
FreeVecPooled(PhoneEntry[i]);
}
}
FreeVecPooled(PhoneEntry);
return(NULL);
}
}
}
}
return(PhoneEntry);
}
/* DeletePhonebook(struct PhoneEntry **PhoneBook,LONG Size,BYTE FreeEntries):
*
* Deallocates a given phone book and its entries if necessary.
*/
VOID __regargs
DeletePhonebook(struct PhoneEntry **Phonebook,LONG Size,BYTE FreeEntries)
{
if(Phonebook)
{
if(FreeEntries)
{
LONG i;
for(i = 0 ; i < Size ; i++)
{
if(Phonebook[i])
{
FreeTimeDateList((struct List *)&Phonebook[i] -> TimeDateList);
if(Phonebook[i] -> Config)
DeleteConfiguration(Phonebook[i] -> Config);
FreeVecPooled(Phonebook[i]);
}
}
}
FreeVecPooled(Phonebook);
}
}